//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.ruoyi.common.utils.jkalman.jama;
import com.ruoyi.common.utils.jkalman.jama.Matrix;

import java.io.Serializable;

public class LUDecomposition implements Serializable {
    private double[][] LU;
    private int m;
    private int n;
    private int pivsign;
    private int[] piv;

    public LUDecomposition(Matrix A) {
        this.LU = A.getArrayCopy();
        this.m = A.getRowDimension();
        this.n = A.getColumnDimension();
        this.piv = new int[this.m];

        for(int i = 0; i < this.m; this.piv[i] = i++) {
        }

        this.pivsign = 1;
        double[] LUcolj = new double[this.m];

        for(int j = 0; j < this.n; ++j) {
            int p;
            for(p = 0; p < this.m; ++p) {
                LUcolj[p] = this.LU[p][j];
            }

            int i;
            double t;
            for(p = 0; p < this.m; ++p) {
                double[] LUrowi = this.LU[p];
                i = Math.min(p, j);
                t = 0.0;

                for(int k = 0; k < i; ++k) {
                    t += LUrowi[k] * LUcolj[k];
                }

                LUrowi[j] = LUcolj[p] -= t;
            }

            p = j;

            for(i = j + 1; i < this.m; ++i) {
                if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p])) {
                    p = i;
                }
            }

            if (p != j) {
                for(i = 0; i < this.n; ++i) {
                    t = this.LU[p][i];
                    this.LU[p][i] = this.LU[j][i];
                    this.LU[j][i] = t;
                }

                i = this.piv[p];
                this.piv[p] = this.piv[j];
                this.piv[j] = i;
                this.pivsign = -this.pivsign;
            }

            if (j < this.m & this.LU[j][j] != 0.0) {
                for(i = j + 1; i < this.m; ++i) {
                    double[] var10000 = this.LU[i];
                    var10000[j] /= this.LU[j][j];
                }
            }
        }

    }

    public boolean isNonsingular() {
        for(int j = 0; j < this.n; ++j) {
            if (this.LU[j][j] == 0.0) {
                return false;
            }
        }

        return true;
    }

    public Matrix getL() {
        Matrix X = new Matrix(this.m, this.n);
        double[][] L = X.getArray();

        for(int i = 0; i < this.m; ++i) {
            for(int j = 0; j < this.n; ++j) {
                if (i > j) {
                    L[i][j] = this.LU[i][j];
                } else if (i == j) {
                    L[i][j] = 1.0;
                } else {
                    L[i][j] = 0.0;
                }
            }
        }

        return X;
    }

    public Matrix getU() {
        Matrix X = new Matrix(this.n, this.n);
        double[][] U = X.getArray();

        for(int i = 0; i < this.n; ++i) {
            for(int j = 0; j < this.n; ++j) {
                if (i <= j) {
                    U[i][j] = this.LU[i][j];
                } else {
                    U[i][j] = 0.0;
                }
            }
        }

        return X;
    }

    public int[] getPivot() {
        int[] p = new int[this.m];

        for(int i = 0; i < this.m; ++i) {
            p[i] = this.piv[i];
        }

        return p;
    }

    public double[] getDoublePivot() {
        double[] vals = new double[this.m];

        for(int i = 0; i < this.m; ++i) {
            vals[i] = (double)this.piv[i];
        }

        return vals;
    }

    public double det() {
        if (this.m != this.n) {
            throw new IllegalArgumentException("Matrix must be square.");
        } else {
            double d = (double)this.pivsign;

            for(int j = 0; j < this.n; ++j) {
                d *= this.LU[j][j];
            }

            return d;
        }
    }

    public Matrix solve(Matrix B) {
        if (B.getRowDimension() != this.m) {
            throw new IllegalArgumentException("Matrix row dimensions must agree.");
        } else if (!this.isNonsingular()) {
            throw new RuntimeException("Matrix is singular.");
        } else {
            int nx = B.getColumnDimension();
            Matrix Xmat = B.getMatrix(this.piv, 0, nx - 1);
            double[][] X = Xmat.getArray();

            int k;
            int i;
            int j;
            for(k = 0; k < this.n; ++k) {
                for(i = k + 1; i < this.n; ++i) {
                    for(j = 0; j < nx; ++j) {
                        X[i][j] -= X[k][j] * this.LU[i][k];
                    }
                }
            }

            for(k = this.n - 1; k >= 0; --k) {
                for(i = 0; i < nx; ++i) {
                    X[k][i] /= this.LU[k][k];
                }

                for(i = 0; i < k; ++i) {
                    for(j = 0; j < nx; ++j) {
                        X[i][j] -= X[k][j] * this.LU[i][k];
                    }
                }
            }

            return Xmat;
        }
    }
}
